package com.originskyseed.platform.job.jobhandler.kpi;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

import com.originskyseed.platform.core.job.biz.model.ReturnT;
import com.originskyseed.platform.core.job.handler.IJobHandler;
import com.originskyseed.platform.core.job.handler.annotation.JobHandler;
import com.originskyseed.platform.core.job.log.JobLogger;
import com.originskyseed.platform.core.mail.api.SendMailUtil;
import com.originskyseed.platform.core.mail.bean.MailMessage;
import com.originskyseed.platform.core.tenant.util.TenantCodeUtil;
import com.originskyseed.platform.count.model.FinancialManage;
import com.originskyseed.platform.count.service.IFinancialManageService;
import com.originskyseed.platform.user.model.Dept;
import com.originskyseed.platform.user.model.UserInfo;
import com.originskyseed.platform.user.service.IDeptService;
import com.originskyseed.platform.user.service.IPlayerService;
import com.originskyseed.platform.user.service.IUserInfoService;

/**
 * 每日发送邮件功能
 * 
 * @Author: twh @date: 2021/8/17
 */

@Component
@JobHandler(value = "everydayKpiHandler")
public class EverydayKpiHandler extends IJobHandler {

	@DubboReference
	private IUserInfoService userInfoService;

	@DubboReference
	private IDeptService deptService;

	@DubboReference
	private IPlayerService playerService;

	@DubboReference
	private IFinancialManageService financialManageService;

	@Override
	public ReturnT<String> execute(String tenantCode) throws Exception {
		try {
			if (StringUtils.isNotEmpty(tenantCode)) {
				TenantCodeUtil.getInstance().createServerTenantCode(tenantCode);
			}
			// 查询推广部门
			Dept queryDept = new Dept();
			queryDept.setSourceSys(2);
			queryDept.setType(3);
			List<Dept> deptList = this.deptService.selectList(queryDept);

			// 查询内容部门
			queryDept.setSourceSys(1);
			queryDept.setType(2);
			List<Dept> contentDeptList = this.deptService.selectList(queryDept);
			deptList.addAll(contentDeptList);

			for (Dept dept:deptList) {
				// 所有下级部门id
				List<String> deptIds = new ArrayList<>();
				this.selectSonId(dept.getCode(), deptIds);
				// 业务员id，部门id
				List<String> otherAccountList ;
				if(dept.getSourceSys()==1){
					otherAccountList = this.userInfoService.selectAnchorOtherIdsByDeptIds(deptIds);
				}else {
					otherAccountList = this.userInfoService.selectSalesmanIdsByDeptIds(deptIds);
				}
				// 用户id
				List<String> userIdList = this.userInfoService.selectUserIdsByDeptIds(deptIds);
				// 查询昨日营收值
				BigDecimal revenueValue = BigDecimal.ZERO;
				// 月营收值
				BigDecimal monthRevenueValue = BigDecimal.ZERO;
				if (otherAccountList.size() > 0) {
					if(dept.getSourceSys()==1){
						revenueValue = this.playerService.selectRevenueValue(-1, otherAccountList, 1);
						monthRevenueValue = this.playerService.selectRevenueValue(2,otherAccountList,1);
					}else {
						revenueValue = this.playerService.selectRevenueValue(-1, otherAccountList, 0);
						monthRevenueValue = this.playerService.selectRevenueValue(2,otherAccountList,0);
					}
				}
				// 昨日kpi
				BigDecimal kpi = BigDecimal.ZERO;
				FinancialManage query = new FinancialManage();
				query.setObjId(dept.getId());
				query.setType(2);
				query.setStartTime(getMonthFirstDay());
				List<FinancialManage> financialManageList = this.financialManageService.selectList(query);
				for (FinancialManage financialManage : financialManageList) {
					kpi = kpi.add(financialManage.getAmount());
				}
				dept.setMonthTargetKpi(kpi);
				kpi = kpi.divide(new BigDecimal(30), 2, BigDecimal.ROUND_HALF_UP);

				// 昨日成本
				// 成本
				BigDecimal basePay = BigDecimal.ZERO;
				// 人力成本
				if (otherAccountList.size() > 0) {
					// 查询数据
					Map<String, Object> map = this.playerService.selectBasePayAndGrossProfit(userIdList,otherAccountList, 0, 0);
					basePay = (BigDecimal) map.get("basePay");
				}
				// 设置的成本
				query.setType(2);
				financialManageList = this.financialManageService.selectList(query);
				for (FinancialManage financialManage : financialManageList) {
					basePay = basePay.add(financialManage.getAmount());
				}
				basePay = basePay.divide(new BigDecimal(30), 2, BigDecimal.ROUND_HALF_UP);

				dept.setBasePay(basePay);
				dept.setTargetKpi(kpi);
				dept.setCompleteKpi(revenueValue);
				if(kpi.compareTo(BigDecimal.ZERO)>0){
					dept.setSurplusKpi(revenueValue.divide(kpi,2, BigDecimal.ROUND_HALF_UP));
				}else {
					dept.setSurplusKpi(BigDecimal.ZERO);
				}
				dept.setMonthCompleteKpi(monthRevenueValue);

				if(monthRevenueValue.compareTo(dept.getMonthTargetKpi())>0){
					dept.setSurplusKpi(BigDecimal.ZERO);
				}else {
					dept.setSurplusKpi(monthRevenueValue.subtract(dept.getMonthTargetKpi()));
				}
			}

			deptList.sort(new Comparator<Dept>() {
				@Override
				public int compare(Dept dept1, Dept dept2) {
					BigDecimal completeSchedule1 = dept1.getCompleteSchedule();
					BigDecimal completeSchedule2 = dept2.getCompleteSchedule();
					return completeSchedule1.compareTo(completeSchedule2);
				}
			});

			for (int i = 0; i < deptList.size(); i++) {
				Dept dept = deptList.get(i);
				List<UserInfo> userInfoList = this.userInfoService.selectUserByDeptId(dept.getId());
				MailMessage mailMessage = new MailMessage();
//					mailMessage.setSender("gztaoliu@163.com");
				mailMessage.setSubject("每日邮件");
				List<String> recipientsList = new ArrayList<>();
				for (UserInfo userInfo: userInfoList) {
					recipientsList.add(userInfo.getEmail());
				}
				mailMessage.setRecipients(recipientsList);
				// 邮件内容读取
				String content = SendMailUtil.readHtmlContent(Thread.currentThread().getContextClassLoader().getResource("sendKpiTemplate.html").getPath());
				// 替换动态数据
				content = content.replaceAll("\\{\\{yesterdayCost\\}\\}", dept.getBasePay().stripTrailingZeros().toPlainString());
				content = content.replaceAll("\\{\\{yesterdayKpi\\}\\}", dept.getTargetKpi().stripTrailingZeros().toPlainString());
				content = content.replaceAll("\\{\\{yesterdayActualKpi\\}\\}", dept.getCompleteKpi().stripTrailingZeros().toPlainString());
				content = content.replaceAll("\\{\\{surplusKpi\\}\\}",dept.getCompleteSchedule().stripTrailingZeros().toPlainString());
				content = content.replaceAll("\\{\\{rank\\}\\}",i+1+"");
				mailMessage.setContent(content);
				boolean flag = SendMailUtil.sendMail(mailMessage);
			}


		} catch (Exception e) {
			JobLogger.log("每日发送邮件功能：" + getExceptionDetail(e));
			return FAIL;
		}
		return SUCCESS;
	}


	/**
	 * 查询组织架构接口
	 *
	 * @param code
	 * @param list
	 * @throws Exception
	 */
	private void selectSonId(String code, List<String> list) throws Exception {
		List<Dept> deptList = this.deptService.selectByParentCode(code);
		if (deptList != null) {
			for (Dept dept1 : deptList) {
				list.add(dept1.getId());
				selectSonId(dept1.getCode(), list);
			}
		}
	}

	/**
	 * 查询本月第一天
	 *
	 * @return
	 * @throws Exception
	 */
	private Date getMonthFirstDay() throws Exception {
		Calendar c = Calendar.getInstance();
		try {
			c.set(Calendar.DATE, 1);
			c.set(Calendar.HOUR_OF_DAY, 0);
			c.set(Calendar.MINUTE, 0);
			c.set(Calendar.SECOND, 0);
			c.set(Calendar.MILLISECOND, 0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return c.getTime();
	}

	/**
	 * 获取异常详细信息，知道出了什么错，错在哪个类的第几行 .
	 *
	 * @param ex
	 * @return
	 */
	public static String getExceptionDetail(Exception ex) {
		String ret = null;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		PrintStream pout = new PrintStream(out);
		try {
			ex.printStackTrace(pout);
			ret = new String(out.toByteArray());
		} catch (Exception e) {
		} finally {
			try {
				pout.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}

}
